package org.joa.examples.philosophers;

import java.util.logging.Logger;

import org.joa.actor.Actor;
import org.joa.actor.Atomic;
import org.joa.actor.exception.RemoteException;
import org.joa.examples.philosophers.generated.Chopstick;
import org.joa.examples.philosophers.generated.Philosopher;
import org.joa.examples.philosophers.generated.PhilosopherProxy;

public class PhilosopherActor extends Actor {
    private static final long serialVersionUID = 1L;
    public static final int MAX_EAT_COUNT = 3;

    private Chopstick leftChopstick;
    private Chopstick rightChopstick;

    private transient static Logger logger = Logger.getLogger(PhilosopherActor.class.getName());

    public PhilosopherActor() {
    }

    public void start(Chopstick leftChopstick, Chopstick rightChopstick) throws RemoteException {
        this.leftChopstick = leftChopstick;
        this.rightChopstick = rightChopstick;

        logger.info("Started philosopher " + toString());

        for (int cnt = 1; cnt <= MAX_EAT_COUNT; cnt++) {
            selfProxy().think();
            selfProxy().eat();
        }
    }

    public void think() {
        sleep(1000);
    }

    @Atomic
    public void eat() throws RemoteException {
        leftChopstick.setHolder(selfProxy());
        rightChopstick.setHolder(selfProxy());

        sleep(1000);

        leftChopstick.setHolder(null);
        rightChopstick.setHolder(null);
    }

    protected void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
        }
    }

    protected Philosopher selfProxy() {
        return PhilosopherProxy.create(self(), self());
    }
}
